#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if TARGET_OS_IPHONE
#import <CFNetwork/CFNetwork.h>
#endif

#define PORT 2048

void ConnectCallBack(CFSocketRef, CFSocketCallBackType, CFDataRef, const void *, void *);

int main(int argc, char **argv) 
{
    /* The server socket */
    CFSocketRef client;

    /* Function to call*/
    char command[] = "";
    char function[] = "STRING";
    command = function;

    /* Used by setsockopt */
    int yes = 1;

    /* Ties command to socket*/
    CFSocketContext CTX = { 0, command, NULL, NULL, NULL };

    /* Create Socket */
    client = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP,
        kCFSocketConnectCallBack, (CFSocketCallBack)ConnectCallBack, &CTX);
    if (client == NULL)
        return EXIT_FAILURE;

    /* Set the port and address we want to listen on */
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_len = sizeof(addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = INADDR_ANY;
    CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));

    CFSocketConnectToAddress(client, connectAddr, 1);
    CFRunLoopSourceRef sourceRef =
        CFSocketCreateRunLoopSource(kCFAllocatorDefault, client, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
    CFRelease(sourceRef);
    CFRunLoopRun();

    /* Get on with our life, instead of waiting for a connect. */
    while(1) {
        struct timeval tv;
        tv.tv_usec = 0;
        tv.tv_sec = 1;        
        select(-1, NULL, NULL, NULL, &tv);
    } 

}


void ConnectCallBack(
    CFSocketRef socket,
    CFSocketCallBackType type,
    CFDataRef address,
    const void *data,
    void *info)
{
    CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;
    CFIndex bytes;
    UInt8 buffer[128];
    UInt8 recv_len = 0, send_len = 0;

    /* The native socket, used for various operations */
    CFSocketNativeHandle sock = CFSocketGetNative(socket);

    /* The joke we stored in the socket context */
    char *joke = info;

    printf("OK. %s", joke);

    send(sock, joke, strlen(joke)+1, 0);
    recv(sock, buffer, sizeof(buffer), 0);
    printf("%sHow lame!\n", buffer);

    close(sock);
    exit(EXIT_SUCCESS);
}

